package sy6_Behavioral_Pattern.mediator.problem;

import java.util.Hashtable;
/*
 * 角色共有抽象中介者Mediator、具体中介者ConcreteMediator、抽象同事类Colleague和具体同事类ConcreteColleague。
 * ConcretMediator可以想象成聊天室，ConcretColleague可以想象为会员。
 * Colleague通过Mediator实现与其它Colleague的交流。因此，Colleague与Mediator存在关联关系，本例中使用聚合关系。
 * 一个具体聊天室应该包含若干会员，因此，ConcretMediator关联ConcretColleague。
 * 
 * 要点：
 * 中介者本身并不产生消息，消息来源于同事类，通过中介者实现消息的收发。
 * 与观察者模式的异同点是：Subject同样聚合多个Observer并由Subject产生消息。
 */
abstract class Mediator {  //抽象中介者
	
	public abstract void registerColleague(Colleague colleague);
	public abstract void dispatcherMessage(String from, String to, String message);
}

abstract class Colleague {  //抽象同事
	
	protected String name;  
	protected Mediator mediator; //Colleague聚合Mediator

	public Colleague(String name) { //构造方法
		this.name = name;
	}
	public void setMediator(Mediator mediator) {  //setter
		this.mediator = mediator;
	}
	public Mediator getMediator() {  //getter
		return mediator;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	
	public void receiveMessage(String from, String message) {  //普通方法：接收来自聊天室的消息
		System.out.println(from + "向" + name + "发送消息，内容为：" + message);
	}

	public abstract void sendMessage(String to, String message);  //声明抽象方法
}

class ConcreteMediator extends Mediator{  //具体中介者，ConcreteMediator关联ConcretColleague
	
	//Hashtable是线程安全，而HashMap则非线程安全
	private Hashtable<String, Colleague> colleagues = new Hashtable<String, Colleague>(); 

	@Override
	public void registerColleague(Colleague colleague) {   //添加会员
		if(!colleagues.contains(colleague)){
			colleagues.put(colleague.getName(), colleague); 
			colleague.setMediator(this);  
		}
	}

	@Override
	public void dispatcherMessage(String from, String to, String message) {
		Colleague colleague = colleagues.get(to);
		message = message.replaceAll("日", "*");  //屏蔽不文明语言
		colleague.receiveMessage(from, message);  //关键
	} 
}

class ConcreteColleague extends Colleague{  //具体同事

	public ConcreteColleague(String name) {  //构造方法
		super(name);
	} 

	@Override
	public void sendMessage(String to, String message) {
		mediator.dispatcherMessage(name, to, message); //调用聊天室的转发消息方法
	}
}

public class Client {  //客户端

	public static void main(String[] args) {
		
		Mediator mediator=new ConcreteMediator();  //创建一个聊天室
		
		Colleague colleague1,colleague2,colleague3;  //创建若干会员并注册
		colleague1=new ConcreteColleague("张三"); mediator.registerColleague(colleague1);
		colleague2=new ConcreteColleague("李四");mediator.registerColleague(colleague2);
		colleague3=new ConcreteColleague("王五");mediator.registerColleague(colleague3);
		
		//会员通过聊天室发送消息
		colleague1.sendMessage("李四","李四，你好！");
		colleague2.sendMessage("张三","张三，你好！");
		colleague1.sendMessage("王五","今天天气不错，有日！");
	}
}
